From 9a82aadca7a127b3b7dc7ab44d602d5c9e9d18c0 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 28 Jul 2020 16:11:45 -0400 Subject: [PATCH] a11y: Set an accessible role for GtkEntry Use the text-box accessible role for GtkEntry and set the placeholder and read-only accessible properties. Update the documentation and add tests. --- docs/reference/gtk/section-accessibility.md | 1 + gtk/gtkentry.c | 25 ++++++++++++- gtk/gtkenums.h | 3 +- testsuite/a11y/entry.c | 41 +++++++++++++++++++++ testsuite/a11y/meson.build | 1 + 5 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 testsuite/a11y/entry.c diff --git a/docs/reference/gtk/section-accessibility.md b/docs/reference/gtk/section-accessibility.md index b8879731d3..78cb8c66fa 100644 --- a/docs/reference/gtk/section-accessibility.md +++ b/docs/reference/gtk/section-accessibility.md @@ -58,6 +58,7 @@ Each role name is part of the #GtkAccessibleRole enumeration. | `SEPARATOR` | A divider that separates sections of content or groups of items | #GtkSeparator | | `SPIN_BUTTON` | A range control that allows seelcting among discrete choices | #GtkSpinButton | | `SWITCH` | A control that represents on/off values | #GtkSwitch | +| `TEXT_BOX` | A type of input that allows free-form text as its value. | #GtkEntry | | `WINDOW` | An application window | #GtkWindow | | `...` | … | diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 5c940fbb0a..f4acb4c17a 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -158,6 +158,10 @@ * applied to the whole text. Note that specifying ranges does not make much * sense with translatable attributes. Use markup embedded in the translatable * content instead. + * + * # Accessibility + * + * GtkEntry uses the #GTK_ACCESSIBLE_ROLE_TEXT_BOX role. */ #define MAX_ICONS 2 @@ -983,6 +987,7 @@ gtk_entry_class_init (GtkEntryClass *class) GTK_TYPE_ENTRY_ICON_POSITION); gtk_widget_class_set_css_name (widget_class, I_("entry")); + gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_TEXT_BOX); } static GtkEditable * @@ -1016,7 +1021,16 @@ gtk_entry_set_property (GObject *object, GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry); if (gtk_editable_delegate_set_property (object, prop_id, value, pspec)) - return; + { + if (prop_id == PROP_EDITING_CANCELED + 1 + GTK_EDITABLE_PROP_EDITABLE) + { + gtk_accessible_update_property (GTK_ACCESSIBLE (entry), + GTK_ACCESSIBLE_PROPERTY_READ_ONLY, !g_value_get_boolean (value), + -1); + } + + return; + } switch (prop_id) { @@ -1028,7 +1042,6 @@ gtk_entry_set_property (GObject *object, case PROP_ACTIVATES_DEFAULT: case PROP_TRUNCATE_MULTILINE: case PROP_OVERWRITE_MODE: - case PROP_PLACEHOLDER_TEXT: case PROP_IM_MODULE: case PROP_INPUT_PURPOSE: case PROP_INPUT_HINTS: @@ -1038,6 +1051,10 @@ gtk_entry_set_property (GObject *object, g_object_set_property (G_OBJECT (priv->text), pspec->name, value); break; + case PROP_PLACEHOLDER_TEXT: + gtk_entry_set_placeholder_text (entry, g_value_get_string (value)); + break; + case PROP_HAS_FRAME: gtk_entry_set_has_frame (entry, g_value_get_boolean (value)); break; @@ -3381,6 +3398,10 @@ gtk_entry_set_placeholder_text (GtkEntry *entry, g_return_if_fail (GTK_IS_ENTRY (entry)); gtk_text_set_placeholder_text (GTK_TEXT (priv->text), text); + + gtk_accessible_update_property (GTK_ACCESSIBLE (entry), + GTK_ACCESSIBLE_PROPERTY_PLACEHOLDER, text, + -1); } /** diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h index 3d3b72b71c..7947e01e82 100644 --- a/gtk/gtkenums.h +++ b/gtk/gtkenums.h @@ -1235,7 +1235,8 @@ typedef enum { * @GTK_ACCESSIBLE_ROLE_TABLE: Unused * @GTK_ACCESSIBLE_ROLE_TAB_LIST: Unused * @GTK_ACCESSIBLE_ROLE_TAB_PANEL: Unused - * @GTK_ACCESSIBLE_ROLE_TEXT_BOX: Unused + * @GTK_ACCESSIBLE_ROLE_TEXT_BOX: A type of input that allows free-form text + * as its value. * @GTK_ACCESSIBLE_ROLE_TIME: Unused * @GTK_ACCESSIBLE_ROLE_TIMER: Unused * @GTK_ACCESSIBLE_ROLE_TOOLBAR: Unused diff --git a/testsuite/a11y/entry.c b/testsuite/a11y/entry.c new file mode 100644 index 0000000000..67cfdcca55 --- /dev/null +++ b/testsuite/a11y/entry.c @@ -0,0 +1,41 @@ +#include + +static void +entry_role (void) +{ + GtkWidget *widget = gtk_entry_new (); + g_object_ref_sink (widget); + + gtk_test_accessible_assert_role (widget, GTK_ACCESSIBLE_ROLE_TEXT_BOX); + + g_object_unref (widget); +} + +static void +entry_properties (void) +{ + GtkWidget *widget = gtk_entry_new (); + g_object_ref_sink (widget); + + gtk_test_accessible_assert_property (widget, GTK_ACCESSIBLE_PROPERTY_PLACEHOLDER, NULL); + gtk_test_accessible_assert_property (widget, GTK_ACCESSIBLE_PROPERTY_READ_ONLY, FALSE); + + gtk_entry_set_placeholder_text (GTK_ENTRY (widget), "Hello"); + gtk_editable_set_editable (GTK_EDITABLE (widget), FALSE); + + gtk_test_accessible_assert_property (widget, GTK_ACCESSIBLE_PROPERTY_PLACEHOLDER, "Hello"); + gtk_test_accessible_assert_property (widget, GTK_ACCESSIBLE_PROPERTY_READ_ONLY, TRUE); + + g_object_unref (widget); +} + +int +main (int argc, char *argv[]) +{ + gtk_test_init (&argc, &argv, NULL); + + g_test_add_func ("/a11y/entry/role", entry_role); + g_test_add_func ("/a11y/entry/properties", entry_properties); + + return g_test_run (); +} diff --git a/testsuite/a11y/meson.build b/testsuite/a11y/meson.build index e56f145c82..81384c7bbf 100644 --- a/testsuite/a11y/meson.build +++ b/testsuite/a11y/meson.build @@ -14,6 +14,7 @@ tests = [ { 'name': 'button' }, { 'name': 'checkbutton' }, { 'name': 'dialog' }, + { 'name': 'entry' }, { 'name': 'image' }, { 'name': 'progressbar' }, { 'name': 'scrollbar' }, -- 2.30.2